use axum::{
    routing::{get, post},
    Router,
};
use std::net::SocketAddr;
use std::sync::Arc;
use tower_http::{cors::Any, services::ServeDir, cors::CorsLayer, trace::TraceLayer};
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt};

mod handlers;
mod services;
mod utils;

use handlers::{download::DownloadState, process::ProcessState};
use utils::AppConfig;

#[tokio::main]
async fn main() {
    // 初始化日志
    tracing_subscriber::registry()
        .with(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "offline_map_service=debug,tower_http=debug".into()),
        )
        .with(tracing_subscriber::fmt::layer())
        .init();

    // 加载配置
    let config = AppConfig::load().expect("加载配置失败");
    
    // 确保必要的目录存在
    utils::file_utils::create_dir_if_not_exists(&config.pbf_download_dir).unwrap();
    utils::file_utils::create_dir_if_not_exists(&config.tiles_output_dir).unwrap();
    utils::file_utils::create_dir_if_not_exists(&config.temp_dir).unwrap();

    // 创建应用状态
    let app_state = Arc::new(utils::AppState {
        config: config.clone(),
        download_state: DownloadState::default(),
        process_state: ProcessState::default(),
    });

    // 配置CORS
    let cors = CorsLayer::new()
        .allow_origin(Any)
        .allow_methods(Any)
        .allow_headers(Any);

    // 构建路由
    let app = Router::new()
        // 静态文件服务
        .nest_service("/static", ServeDir::new("src/static"))
        // 瓦片服务
        .nest_service("/tiles", ServeDir::new(&config.tiles_output_dir))
        // API路由
        .route("/", get(handlers::root::get_index))
        .route("/api/download/pbf", post(handlers::download::download_pbf))
        .route("/api/download/progress", get(handlers::download::get_download_progress))
        .route("/api/process/convert", post(handlers::process::convert_to_tiles))
        .route("/api/process/progress", get(handlers::process::get_process_progress))
        // 状态管理
        .with_state(app_state)
        // 中间件
        .layer(cors)
        .layer(TraceLayer::new_for_http());

    // 绑定地址并启动服务
    let addr = SocketAddr::from(([0, 0, 0, 0], config.server_port));
    tracing::info!("服务启动在 http://{}", addr);
    let listener = tokio::net::TcpListener::bind(addr).await.unwrap();

        // Ensure we use a shutdown signal to abort the deletion task.
    axum::serve(listener, app.into_make_service_with_connect_info::<std::net::SocketAddr>())
        .await
        .expect("服务器启动失败");
}
